package br.com.rookgraph.heuristica;

import br.com.rookgraph.Edge;
import br.com.rookgraph.Graph;

public class Plus2 implements Heuristica {

	@Override
	public Edge selectForCut(Edge candidate, Edge edgeCut) {

		Edge edgeSelect = edgeCut;

// Escolhe o delta mais negativo, ou seja a maior quantidade de vertices que deixarao de ser branches
		if (edgeSelect == null || candidate.beta < edgeSelect.beta) {
			edgeSelect = candidate;

		} else if (candidate.beta == edgeSelect.beta) {
			
			if (candidate.gama < edgeSelect.gama) {
				edgeSelect = candidate;

			 }else if (candidate.gama == edgeSelect.gama){

				if( candidate.sigma < edgeSelect.sigma){
					edgeSelect = candidate;

	/*			}else if( candidate.sigma == edgeSelect.sigma){

					if( candidate.sigmaLine > edgeSelect.sigmaLine){
						edgeSelect = candidate;
					}
	*/			}
				
			}
		}				
		return edgeSelect;
	}

	@Override
	public Edge selectForRep(Edge candidate, Edge edgeRep) {

		// Escolhe a aresta onde a troca for a Melhor, ou seja onde haverá a MAIOR perda de branches (o mais negativo)					
		if (edgeRep == null || Math.abs(candidate.beta) < Math.abs(edgeRep.beta)) {
			edgeRep = candidate;

		} else if (Math.abs(candidate.beta) == Math.abs(edgeRep.beta)) {
			
			// adicionada em 03/11
			//edgeRep = candidate;
			
			if (candidate.gama < edgeRep.gama) {
				edgeRep = candidate;

			}else if (candidate.gama == edgeRep.gama){

				if (candidate.sigma > edgeRep.sigma){
					edgeRep = candidate;

			/*	}else if( candidate.sigma == edgeRep.sigma){

					if( candidate.sigmaLine > edgeRep.sigmaLine){
						edgeRep = candidate;
					}
			*/		
				}
			}
			
		}
		return edgeRep;
	}

	/* (non-Javadoc)
	 * @see br.com.rookgraph.heuristica.Heuristica#isVantajoso(br.com.rookgraph.Edge, br.com.rookgraph.Edge)
	 *
	 * Esse metodo pode ser melhorado chamando um dos acima
	 * -TODO verifica isso
	 *
	 */
	@Override
	public boolean isVantajoso(Edge edgeRep, Edge edgeCut) {

		int deltaTroca = 100000000;

		// Escolhe a aresta onde a troca for a Melhor, ou seja onde haverá a MAIOR perda de branches (o mais negativo)			

		deltaTroca = edgeRep.beta + edgeCut.beta;

		if (deltaTroca < 0) {
			edgeRep = edgeCut;

		 }else if (deltaTroca == 0){
		
			// adicionada em 03/12  -- loop
			//edgeRep = edgeCut;
			
			if (edgeRep.gama < edgeCut.gama) {
				edgeRep = edgeCut;
				
			}else if (edgeRep.gama == edgeCut.gama){
				
				if (edgeRep.sigma > edgeCut.sigma){
					edgeRep = edgeCut;
			
			/*	}else if (edgeRep.sigma == edgeCut.sigma){

					if (edgeRep.sigmaLine > edgeCut.sigmaLine){
						edgeRep = edgeCut;
					}
			*/		
				}				
			}
		}
		
		return edgeRep == edgeCut;
	}

		
	public boolean ganhoTroca (Edge edgeRep, Edge edgeCut) {

		int diffAlfaCandidata, diffAlfaEntrada, diffGamaCandidata, diffGamaEntrada,diffSigmaCandidata,diffSigmaEntrada;
		
		// falta pegar a ordem correta da matriz - quantidade de vertices	
		if (edgeRep.gama == 2) { 
			edgeRep.gama = 100;
		}else if ( edgeRep.gama == 1) { 
			edgeRep.gama = 101;
		
		}
		diffAlfaEntrada = 1000000;
		diffGamaEntrada =  1000000;
		diffSigmaEntrada = 1000000;

		diffAlfaCandidata = edgeRep.alfa-edgeCut.alfa;
		diffGamaCandidata = edgeRep.gama-edgeCut.gama;

		// valorizar o maior sigma na entrada
		diffSigmaCandidata = edgeCut.sigma-edgeRep.sigma;

		if (diffAlfaCandidata < diffAlfaEntrada){	
			return true;

		}else if (diffAlfaCandidata == diffAlfaEntrada) { 

			if (diffGamaCandidata < diffGamaEntrada) {
				return  true;

				}else if (diffGamaCandidata == diffGamaEntrada) {

					if (diffSigmaCandidata > diffSigmaEntrada) {
						return  true;
					}
				}
			}
		return false;	
	}

	@Override
	public boolean melhorTroca(Graph tree, Edge edgeRep, Edge edgeCut,
			Edge edgeEntrada, Edge edgeSaida) {
		// TODO Auto-generated method stub
		return false;
	}
}